home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 1 (Walnut Creek)
/
Aminet - June 1993 [Walnut Creek].iso
/
aminet
/
util
/
wb
/
mbm.lzh
/
switcher.c
< prev
Wrap
C/C++ Source or Header
|
1992-04-13
|
7KB
|
250 lines
/*
* Switcher.c - bring up a requester listing screens & windows, and bring
* the one selected to the front. Shut down on window deactivation.
* ===build
* % lc -Lcdn -v -tr -O -mcs -r -rr -b -cfsu -d0 switcher ; output= switcher inputs= switcher.c
* ===endbuild
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <intuition/gadgetclass.h>
#include <graphics/gfxmacros.h>
#include <graphics/gfxbase.h>
#include <utility/tagitem.h>
#include <clib/macros.h>
#include <string.h>
#include <libraries/gadtools.h>
#include <clib/exec_protos.h>
#include <pragmas/exec.h>
#include <clib/graphics_protos.h>
#include <pragmas/graphics.h>
#include <clib/intuition_protos.h>
#include <pragmas/intuition.h>
#include <clib/gadtools_protos.h>
#include <pragmas/gadtools.h>
extern struct GfxBase *GfxBase = NULL;
extern struct IntuitionBase *IntuitionBase = NULL;
extern struct Library *GadToolsBase = NULL;
/*
* Test code; generate a main to call the switcher.
*/
void
_main(char *x) {
void switcher(void);
/* Open libraries */
GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 36L);
IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 36L);
GadToolsBase = OpenLibrary("gadtools.library", 36L);
/* Run the switcher */
if (GfxBase && IntuitionBase && GadToolsBase) switcher();
/* and shut them down */
if (GadToolsBase) CloseLibrary(GadToolsBase);
if (IntuitionBase) CloseLibrary(IntuitionBase);
if (GfxBase) CloseLibrary(GfxBase);
}
static struct TagItem windowtags[] = { WA_AutoAdjust, TRUE, TAG_DONE } ;
static struct ExtNewWindow mynewwin =
{
0, 0, /* LeftEdge, TopEdge */
0, 0, /* Width, Height filled in later */
-1, -1, /* DetailPen, BlockPen */
IDCMP_GADGETUP | IDCMP_GADGETDOWN | IDCMP_REFRESHWINDOW | IDCMP_INACTIVEWINDOW,
WFLG_ACTIVATE | WFLG_BORDERLESS | WFLG_SIMPLE_REFRESH | WFLG_NW_EXTENDED,
NULL, /* FirstGadget */
NULL, /* CheckMark */
NULL, /* Title */
NULL, /* Screen */
NULL, /* BitMap */
0, 0, /* MinWidth, MinHeight */
0, 0, /* MaxWidth, MaxHeight */
CUSTOMSCREEN, /* Type */
windowtags /* Tags */
};
struct MBMNode {
struct Node m_Node;
struct Window *m_Window;
struct Screen *m_Screen;
};
/* My globals */
static struct Remember *RKey = NULL;
#define MAXNAMELEN 40
static USHORT
AddName(struct Screen *s, struct Window *w, struct List *lh) {
struct MBMNode *node;
char namebuf[MAXNAMELEN + 1];
if (w) {
if (!w->Title || !*w->Title) return 0;
*namebuf = ' ';
strncpy(namebuf + 1, w->Title, MAXNAMELEN - 1);
}
else {
*namebuf = '\273';
if (s->DefaultTitle) strncpy(namebuf + 1, s->DefaultTitle, MAXNAMELEN - 1);
else namebuf[1] = '\0';
}
namebuf[MAXNAMELEN] = '\0'; /* Insurance */
node = (struct MBMNode *)AllocRemember(&RKey, sizeof(struct MBMNode), MEMF_CLEAR);
node->m_Node.ln_Name = strdup(namebuf);
node->m_Window = w;
node->m_Screen = s;
AddTail(lh, node);
return strlen(namebuf);
}
/*
* Gadgets Finds the data to go in the gadget, and set various sizes based on
* that data.
*/
static struct Gadget *
Gadgets(struct Gadget **glistptr, void *vi, struct TextFont *f, struct List *lh)
{
struct TagItem gadtags[2] ;
void NewList(struct List *);
struct NewGadget ng;
struct Gadget *gad;
LONG lock;
USHORT tmplen, longname = 0, length;
struct Screen *s;
struct Window *w;
gad = CreateContext(glistptr);
NewList(lh);
lock = LockIBase(0L);
for (s = IntuitionBase -> FirstScreen, length = 0; s;
s = s -> NextScreen, length += 1) {
if ((tmplen = AddName(s, NULL, lh)) > longname) longname = tmplen;
for (w = s->FirstWindow; w; w = w -> NextWindow) {
if ((tmplen = AddName(s, w, lh)) > longname) longname = tmplen;
if (tmplen) length += 1;
}
}
UnlockIBase(lock);
if (length > 20) length = 20;
ng.ng_Width = mynewwin.Width = f->tf_XSize * (MAXNAMELEN + 2);
ng.ng_Height = mynewwin.Height = f->tf_YSize * length + 6;
ng.ng_LeftEdge = 0;
ng.ng_TopEdge = 0;
ng.ng_GadgetText = NULL;
ng.ng_TextAttr = NULL;
ng.ng_Flags = NG_HIGHLABEL|PLACETEXT_LEFT;
ng.ng_VisualInfo = vi;
gadtags[0].ti_Tag = GTLV_Labels;
gadtags[0].ti_Data = (ULONG) lh;
gadtags[1].ti_Tag = TAG_DONE;
gad = CreateGadgetA(LISTVIEW_KIND, gad, &ng, gadtags);
/* Finsh tweaking the window */
mynewwin.LeftEdge = IntuitionBase->ActiveScreen->MouseX - (mynewwin.Width / 2);
if (mynewwin.LeftEdge < 0) mynewwin.LeftEdge = 0;
mynewwin.TopEdge = IntuitionBase->ActiveScreen->MouseY - (mynewwin.Height / 2);
if (mynewwin.TopEdge < 0) mynewwin.TopEdge = 0;
return(gad);
}
/*
* Start of the switcher proper.
*/
static void
switcher(void) {
struct List lh;
BOOL terminated = FALSE;
struct Screen *s = NULL;
struct Window *w;
struct Gadget *glist = NULL;
struct Window *mywin = NULL;
void *vi = NULL;
struct IntuiMessage *imsg;
struct Gadget *gad;
ULONG imsgClass;
UWORD imsgCode, CountCode;
LONG lock;
struct MBMNode *NodeCode;
/*
* This probably all ought to happen inside a LockIBase, but...
*/
/* Information needed to open the window */
s = IntuitionBase->ActiveScreen;
if (!(vi = GetVisualInfoA(s, NULL))) goto out;
if (!Gadgets(&glist, vi, s->RastPort.Font, &lh)) goto out;
mynewwin.FirstGadget = glist;
mynewwin.Screen = s;
/* Open the window, and render it */
if (!(mywin = OpenWindow(&mynewwin))) goto out;
GT_RefreshWindow(mywin, NULL);
while (!terminated) {
Wait (1 << mywin->UserPort->mp_SigBit);
/* GT_GetIMsg() returns a cooked-up IntuiMessage with
* more friendly information for complex gadget classes. Use
* it wherever you get IntuiMessages:
*/
while ((!terminated) && (imsg = GT_GetIMsg(mywin->UserPort)))
{
imsgClass = imsg->Class;
imsgCode = imsg->Code;
/* Presuming a gadget, of course, but no harm... */
gad = (struct Gadget *)imsg->IAddress;
/* Use the toolkit message-replying function here... */
GT_ReplyIMsg(imsg);
switch (imsgClass)
{
case IDCMP_GADGETUP:
for (CountCode = imsgCode, NodeCode = (struct MBMNode *) lh.lh_Head; CountCode--;
NodeCode = (struct MBMNode *) NodeCode->m_Node.ln_Succ)
;
lock = LockIBase(0);
for (s = IntuitionBase->FirstScreen; s; s = s->NextScreen)
if (s == NodeCode->m_Screen)
break;
if (!s) {
UnlockIBase(lock);
break;
}
ScreenToFront(s);
for (w = s->FirstWindow; w; w = w->NextWindow)
if (w == NodeCode->m_Window) break;
if (w) WindowToFront(w);
UnlockIBase(lock);
terminated = 1;
break;
case IDCMP_INACTIVEWINDOW:
terminated = 1;
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(mywin);
GT_EndRefresh(mywin, TRUE);
break;
}
}
}
out:
if (mywin) CloseWindow(mywin);
FreeVisualInfo(vi);
FreeGadgets(glist);
if (RKey) FreeRemember(&RKey, TRUE);
}